package com.matchmealpha;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.cookie.ClientCookie;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;

import android.graphics.Bitmap;
import android.util.Log;

public class HttpRequest {

	DefaultHttpClient httpClient;
	HttpContext localContext;
	private String ret;

	HttpResponse response = null;
	HttpPost httpPost = null;
	HttpGet httpGet = null;

	public HttpRequest() {
		HttpParams myParams = new BasicHttpParams();

		HttpConnectionParams.setConnectionTimeout(myParams, 10000);
		HttpConnectionParams.setSoTimeout(myParams, 10000);
		httpClient = new DefaultHttpClient(myParams);
		localContext = new BasicHttpContext();
	}

	public HttpRequest(String session_id) {
		HttpParams myParams = new BasicHttpParams();

		HttpConnectionParams.setConnectionTimeout(myParams, 10000);
		HttpConnectionParams.setSoTimeout(myParams, 10000);
		httpClient = new DefaultHttpClient(myParams);
		localContext = new BasicHttpContext();
		BasicClientCookie cookie = new BasicClientCookie("sessionid",
				session_id);
		cookie.setExpiryDate(new Date(System.currentTimeMillis() + 120000));
		cookie.setDomain("matchmeapp.appspot.com");
		cookie.setAttribute(ClientCookie.VERSION_ATTR, "0");
		cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "matchmeapp.appspot.com");
		cookie.setPath("/");

		httpClient.getCookieStore().addCookie(cookie);
	}

	public void clearCookies() {
		httpClient.getCookieStore().clear();
	}

	public String getSessionID() {

		for (Cookie c : httpClient.getCookieStore().getCookies()) {
			if (c.getName().equals("sessionid")) {
				Log.d("Your App Name Here", "cookie");
				return c.getValue();
			}
		}
		return null;
	}

	public void abort() {
		try {
			if (httpClient != null) {
				System.out.println("Abort.");
				httpPost.abort();
			}
		} catch (Exception e) {
			System.out.println("Your App Name Here" + e);
		}
	}

	public String sendPost(String url, String data) {
		return sendPost(url, data, null);
	}

	public String sendJSONPost(String url, JSONObject data) {
		return sendPost(url, data.toString(), "application/json");
	}

	public String sendPost(String url, String data, String contentType) {
		ret = null;

		// httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY,
		// CookiePolicy.RFC_2109);
		httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY,
				CookiePolicy.NETSCAPE);

		httpPost = new HttpPost(url);
		response = null;

		StringEntity tmp = null;

		Log.d("Your App Name Here", "Setting httpPost headers");

		httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE");
		httpPost
				.setHeader(
						"Accept",
						"text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");

		if (contentType != null) {
			httpPost.setHeader("Content-Type", contentType);
		} else {
			httpPost.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
		}

		try {
			tmp = new StringEntity(data, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			Log.e("Your App Name Here",
					"HttpUtils : UnsupportedEncodingException : " + e);
		}

		httpPost.setEntity(tmp);

		Log.d("Your App Name Here", url + "?" + data);

		Log.d("MY APP", "Initial set of cookies:");
		List<Cookie> cookies = httpClient.getCookieStore().getCookies();
		if (cookies.isEmpty()) {
			Log.d("MY APP", "None");
		} else {
			for (int i = 0; i < cookies.size(); i++) {
				Log.d("MY APP", "- " + cookies.get(i).toString());
			}
		}

		try {
			response = httpClient.execute(httpPost, localContext);

			if (response != null) {
				ret = EntityUtils.toString(response.getEntity());
			}
		} catch (Exception e) {
			Log.e("Your App Name Here", "HttpUtils: " + e);
		}

		Log.d("Your App Name Here", "Returning value:" + ret);

		Log.d("MY APP", "final set of cookies:");
		cookies = httpClient.getCookieStore().getCookies();
		if (cookies.isEmpty()) {
			Log.d("MY APP", "None");
		} else {
			for (int i = 0; i < cookies.size(); i++) {
				Log.d("MY APP", "- " + cookies.get(i).toString());
			}
		}
		return ret;
	}

	public String sendGet(String url) {
		httpGet = new HttpGet(url);

		try {
			response = httpClient.execute(httpGet);
		} catch (Exception e) {
			Log.e("Your App Name Here", e.getMessage());
		}

		// int status = response.getStatusLine().getStatusCode();

		// we assume that the response body contains the error message
		try {
			ret = EntityUtils.toString(response.getEntity());
		} catch (IOException e) {
			Log.e("Your App Name Here", e.getMessage());
		}

		return ret;
	}

	public byte[] getByteArray(String url) {
		httpGet = new HttpGet(url);
		byte[] array = null;

		Log.d("Your App Name Here", "in GET");

		try {
			response = httpClient.execute(httpGet);
		} catch (Exception e) {
			Log.e("Your App Name Here", e.getMessage());
		}

		// int status = response.getStatusLine().getStatusCode();

		// we assume that the response body contains the error message

		try {
			// Log.d("GET SIZE ", EntityUtils.toString(response.getEntity()) +
			// "");
			array = EntityUtils.toByteArray(response.getEntity());
			// Log.d("Your App Name Here",
			// EntityUtils.toString(response.getEntity()) + "");
		} catch (IOException e) {
			Log.e("Your App Name Here", e.getMessage());
		}

		Log.d("Your App Name Here", array.length + "");

		return array;
	}

	public InputStream getHttpStream(String urlString) throws IOException {
		InputStream in = null;
		int response = -1;

		URL url = new URL(urlString);
		URLConnection conn = url.openConnection();

		if (!(conn instanceof HttpURLConnection))
			throw new IOException("Not an HTTP connection");

		try {
			HttpURLConnection httpConn = (HttpURLConnection) conn;
			httpConn.setAllowUserInteraction(false);
			httpConn.setInstanceFollowRedirects(true);
			httpConn.setRequestMethod("GET");
			httpConn.connect();

			response = httpConn.getResponseCode();

			if (response == HttpURLConnection.HTTP_OK) {
				in = httpConn.getInputStream();
			}
		} catch (Exception e) {
			throw new IOException("Error connecting");
		} // end try-catch

		return in;
	}

	/**
	 * 
	 * @param url
	 * @param postType
	 *            : 1 - create post, 2 - complete post
	 * @param post
	 * @return - postId if type 1 or sucess or failed for type 2
	 */
	public String sendMultipartPost(int postType, Post post, int alertid) {
		Log.d("MY HTTP REQUEST", "UPLOAD: SendMultipartFile");
		// httpClient = new DefaultHttpClient();
		MultipartEntity mpEntity;
		httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY,
				CookiePolicy.NETSCAPE);

		//int[] array = post.getPicID();
		//byte[] barray = MatchMeTabWidget.intArrayToByte(array);

		//Log.d("REQUEST", "BYTES: " + barray.length);

		if (postType == 1) {
			httpPost = new HttpPost(MatchMeTabWidget.MM_SERVER + "/create_post");
			mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

			try {
				mpEntity.addPart("userid2", new StringBody(post.getUserID2()));
				mpEntity.addPart("location1", new StringBody(post
						.getLocation1()));
				mpEntity.addPart("description1", new StringBody(post
						.getDescription1()));
				
				ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                post.getBitMapImage().compress(Bitmap.CompressFormat.PNG, 100, baos); //bm is the bitmap object   
                byte[] b = baos.toByteArray();
                mpEntity.addPart("file", new ByteArrayBody(b, "data"));
			} catch (UnsupportedEncodingException e1) {
				e1.printStackTrace();
				return MatchMeTabWidget.REQUEST_FAILURE;
			}
		} else {
			httpPost = new HttpPost(MatchMeTabWidget.MM_SERVER
					+ "/accept_matchme");
			mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
			try {
				mpEntity.addPart("postid",
						new StringBody(post.getPostID() + ""));
				Log.d("MY HTTP ALERTID:  ", "" + alertid);

				mpEntity.addPart("alertid", new StringBody(alertid + ""));
				mpEntity.addPart("location2", new StringBody(post
						.getLocation2()));
				mpEntity.addPart("description2", new StringBody(post
						.getDescription2()));
				ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                post.getBitMapImage().compress(Bitmap.CompressFormat.PNG, 100, baos); //bm is the bitmap object   
                byte[] b = baos.toByteArray();
				mpEntity.addPart("file", new ByteArrayBody(b, "data"));
				
			} catch (UnsupportedEncodingException e1) {
				Log
						.d("MY HTTP REQUEST",
								"UPLOAD: UnsupportedEncodingException");
				e1.printStackTrace();
				return MatchMeTabWidget.REQUEST_FAILURE;
			}
		}

		httpPost.setEntity(mpEntity);
		Log.d("MY HTTP REQUEST", "UPLOAD: executing request: "
				+ httpPost.getRequestLine());
		Log.d("MY HTTP REQUEST", "UPLOAD: request: "
				+ httpPost.getEntity().getContentType().toString());

		Log.d("MY APP", "Initial set of cookies:");
		List<Cookie> cookies = httpClient.getCookieStore().getCookies();
		if (cookies.isEmpty()) {
			Log.d("MY APP", "None");
		} else {
			for (int i = 0; i < cookies.size(); i++) {
				Log.d("MY APP", "- " + cookies.get(i).toString());
			}
		}

		HttpResponse response;
		try {
			Log.d("MY HTTP REQUEST", "UPLOAD: about to execute");
			response = httpClient.execute(httpPost);
			Log.d("MY HTTP REQUEST", "UPLOAD: executed");
			HttpEntity resEntity = response.getEntity();
			Log.d("MY HTTP REQUEST", "UPLOAD: respose code: "
					+ response.getStatusLine().toString());
			if (resEntity != null) {
				Log.d("MY HTTP REQUEST", "UPLOAD: "
						+ EntityUtils.toString(resEntity));
			}
			if (resEntity != null) {
				resEntity.consumeContent();
			}
			Log.d("MY HTTP REQUEST", "UPLOAD RESPONSE: " + response.toString());
			return response.toString();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return MatchMeTabWidget.REQUEST_FAILURE;
		} catch (IOException e) {
			e.printStackTrace();
			return MatchMeTabWidget.REQUEST_FAILURE;
		}
	}
}